<?php

namespace app\common\cachemodel\zl6;

use app\common\model\BaseCache;
use XznsTools\cache\CacheManage;

class Zl6MeditationTodayPlayDuration extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl6_meditation_today_play_duration';

    protected $cacheModel = 'meditation.today_play_duration';

    /**
     * 写入数据
     * @param array $data
     * @return int
     */
    public function SaveData(array $data)
    {
        try
        {
            $id = $this->insertGetId($data);

            return (int)$id;
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return 0;
        }
    }

    /**
     * 更新 数据
     * @param int $id
     * @param int $uid
     * @param int $date
     * @param $data
     * @return bool
     */
    public function UpdateData(int $id, int $uid, int $date, $data)
    {
        try
        {
            $this->where(['id' => $id])->update($data);
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':' . $date)->setCache($data);
            return true;
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return false;
        }
    }

    /**
     * 获取今日 播放时长信息
     */
    public function getTodayPlayDuration(int $uid, int $date, array $field = [])
    {
        $resData = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . ':' . $date)->getDataAndSet(function () use ($uid, $date)
        {
            try
            {
                return $this->where(['uid' => $uid, 'date' => $date])->findOrFail()->toArray();
            }
            catch (\Exception $e)
            {
                return null;
            }
        }, $field);

        if ($resData)
        {
            $resData = arrayKeyData2int($resData, ['id', 'uid', 'date', 'duration', 'is_crescent', 'is_bad_luck', 'continuous_day', 'create_time']);
        }

        return $resData;
    }

    /**
     * 获取 指定日期之前的 播放时长 统计信息
     * 不包含 今日 【播放时长、今天冥想的天数、最大连线天数】
     * @param int $uid
     * @param int $dateInt
     * @param array $field
     * @return array
     * @throws \Exception
     */
    public function getPlayDurationTotalData(int $uid, int $dateInt, array $field = [])
    {
        $resData = CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('total_data', $uid . ':' . $dateInt)
            ->setCacheTime(86400)->getDataAndSet(function () use ($uid, $dateInt)
            {
                try
                {
                    $data = $this->where(['uid' => $uid, 'date' => ['<', $dateInt]])->field('sum(duration) as total_duration,count(id) as total_day,max(continuous_day) as max_continuous_day,sum(is_crescent) as crescent_day,sum(is_bad_luck) as bad_luck_day')->findOrFail()->toArray();

                    $data['total_duration'] = $data['total_duration'] ? (int)$data['total_duration'] : 0;
                    $data['total_day'] = $data['total_day'] ? (int)$data['total_day'] : 0;
                    $data['max_continuous_day'] = $data['max_continuous_day'] ? (int)$data['max_continuous_day'] : 0;
                    $data['crescent_day'] = $data['crescent_day'] ? (int)$data['crescent_day'] : 0;
                    $data['bad_luck_day'] = $data['bad_luck_day'] ? (int)$data['bad_luck_day'] : 0;

                    return $data;
                }
                catch (\Exception $e)
                {
                    return null;
                }
            }, $field, 'total_data');

        if ($resData)
        {
            $resData = arrayKeyData2int($resData, ['total_duration', 'total_day', 'max_continuous_day', 'crescent_day', 'bad_luck_day']);
        }

        return $resData;
    }

    /**
     * 获取 指定月份 播放统计信息
     * @param int $uid
     * @param int $monthInt
     * @param array $field
     * @return array
     * @throws \Exception
     */
    public function getPlayDurationMonthData(int $uid, int $monthInt, array $field = [])
    {
        $resData = CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('month_total_data', $uid . ':' . $monthInt)
            ->setCacheType('string')->getDataAndSet(function () use ($uid, $monthInt)
            {
                try
                {
                    $startMonth = (int)($monthInt . '01');
                    $endMonth = (int)date('Ymd', strtotime($startMonth . ' +1 month'));

                    $data = $this->where(['uid' => $uid, 'date' => ['between', [$startMonth, $endMonth]]])->column('is_crescent,is_bad_luck', 'date');

                    $resData = [];
                    foreach ($data as $k => $dataItem)
                    {
                        $resData[] = [
                            'date' => date('Y-m-d', strtotime($dataItem['date'])),
                            'is_crescent' => (int)$dataItem['is_crescent'],
                            'is_bad_luck' => (int)$dataItem['is_bad_luck'],
                        ];
                    }

                    return json_encode($resData, JSON_UNESCAPED_UNICODE);
                }
                catch (\Exception $e)
                {
                    return [];
                }
            }, $field, 'month_total_data');

        return $resData ? json_decode($resData, true) : [];
    }

    /**
     * 设置今日 播放时长
     * @param int $uid
     * @param int $dateInt 日期 20230101
     * @param int $incDuration 增加播放时长
     * @param int $isCrescent
     * @param int $isBadLuck
     * @return void
     * @throws \Exception
     */
    public function setTodayPlayDuration(int $uid, int $dateInt, int $incDuration, int $isCrescent, int $isBadLuck)
    {
        $nowTime = time();
        $todayPlayDurationInfo = $this->getTodayPlayDuration($uid, $dateInt);
        if ($todayPlayDurationInfo)
        { // 存在  更新 今日播放时长
            $data = [
                'duration' => $todayPlayDurationInfo['duration'] + $incDuration,
            ];
            if ($isCrescent === 1)
            {
                $data['is_crescent'] = 1;
            }
            if ($isBadLuck === 1)
            {
                $data['is_crescent'] = 1;
            }
            $this->UpdateData($todayPlayDurationInfo['id'], $uid, $dateInt, $data);
            if ($isCrescent === 1 || $isBadLuck === 1)
            {
                // 删除 本月 统计信息 缓存
                CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('month_total_data', $uid . ':' . date('Ym'))->rmCache('month_total_data');
            }
        } else
        { // 不存在 新增 今日播放时长
            // 取今日 零点时间戳
            $zeroTimestamp = strtotime(date('Y-m-d', time()));
            $duration = $nowTime - $zeroTimestamp;
            // 如果播放时间 跨天 则重新计算 播放时长   如果 当前时间-零点时间小于 增加播放时长 则说明跨天
            $duration = min($duration, $incDuration);
            // 取昨日日期
            $yesterDate = (int)date('Ymd', strtotime('-1 day'));
            $yesterdayPlayDurationInfo = $this->getTodayPlayDuration($uid, $yesterDate);
            if ($yesterdayPlayDurationInfo)
            {   // 计算 连线日期
                $continuousDay = $yesterdayPlayDurationInfo['continuous_day'] + 1;
            } else
            {   // 定义 连线日期
                $continuousDay = 1;
            }

            $resData = [
                'uid' => $uid,
                'date' => $dateInt,
                'duration' => $duration,
                'is_crescent' => $isCrescent,
                'is_bad_luck' => $isBadLuck,
                'continuous_day' => $continuousDay,  // 连线天数
                'create_time' => $nowTime,
            ];
            $this->SaveData($resData);
            // 删除 本月 统计信息 缓存
            CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('month_total_data', $uid . ':' . date('Ym'))->rmCache('month_total_data');
            // 删除 统计信息 缓存   -- 作废  今日播放信息 不影响 统计信息
//            CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('total_data', $uid . ':' . $dateInt)->rmCache('total_data');
        }
    }
}